﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Onshi.POS.AccesoDatos;
using Onshi.POS.AccesoDatos.Interfaces;
using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Objetos;

namespace Onshi.POS.Repositorios
{
    public class RepositorioArticulo : RepositorioEntidad<Articulo, Int32>
    {
        #region Constructores

        public RepositorioArticulo()
            : base()
        {
            servicioDatosArticulo = new ServicioDatosArticulo();
            repositorioTipoArticulo = new RepositorioTipoArticulo();
            repositorioRubroArticulo = new RepositorioRubroArticulo();
            repositorioDescuentoRecargo = new RepositorioDescuentoRecargo();
            repositorioMarca = new RepositorioMarca();
            repositorioTipoComisionArticulo = new RepositorioTipoComisionArticulo();
            repositorioTipoImpuestoArticulo = new RepositorioTipoImpuestoArticulo();
            repositorioTipoCostoArticulo = new RepositorioTipoCostoArticulo();
        }

        #endregion

        #region Atributos

        private IServicioDatosArticulo servicioDatosArticulo;
        private RepositorioTipoArticulo repositorioTipoArticulo;
        private RepositorioRubroArticulo repositorioRubroArticulo;
        private RepositorioDescuentoRecargo repositorioDescuentoRecargo;
        private RepositorioMarca repositorioMarca;
        private RepositorioTipoComisionArticulo repositorioTipoComisionArticulo;
        private RepositorioTipoImpuestoArticulo repositorioTipoImpuestoArticulo;
        private RepositorioTipoCostoArticulo repositorioTipoCostoArticulo;
        #endregion

        #region Propiedades

        private IServicioDatosArticulo ServicioDatosArticulo
        {
            get { return servicioDatosArticulo; }
        }

        private RepositorioTipoArticulo RepositorioTipoArticulo
        {
            get { return repositorioTipoArticulo; }
        }

        private RepositorioRubroArticulo RepositorioRubroArticulo
        {
            get { return repositorioRubroArticulo; }
        }

        private RepositorioDescuentoRecargo RepositorioDescuentoRecargo
        {
            get { return repositorioDescuentoRecargo; }
        }

        private RepositorioMarca RepositorioMarca
        {
            get { return repositorioMarca; }
        }

        private RepositorioTipoComisionArticulo RepositorioTipoComisionArticulo
        {
            get { return repositorioTipoComisionArticulo; }
        }

        private RepositorioTipoImpuestoArticulo RepositorioTipoImpuestoArticulo
        {
            get { return repositorioTipoImpuestoArticulo; }
        }

        private RepositorioTipoCostoArticulo RepositorioTipoCostoArticulo
        {
            get { return repositorioTipoCostoArticulo; }
        }

        private RepositorioPromocion RepositorioPromocion 
        {
            get { return new RepositorioPromocion(); }
        }
        #endregion

        #region Metodos

        protected override Articulo FilaAEntidad(DataRow fila)
        {
            Articulo articulo = new Articulo();
            articulo.Id = (Int32)fila["IdArticulo"];
            articulo.Tipo = RepositorioTipoArticulo.DevolverPorId((Byte)fila["IdTipoArticulo"]);

            articulo.Rubro = RepositorioRubroArticulo.DevolverPorId((Int32)fila["idRubroArticulo"]);
            articulo.DescuentoRecargo = RepositorioDescuentoRecargo.DevolverPorId((Int32)fila["idDescuentoRecargo"]);
            articulo.Marca = RepositorioMarca.DevolverPorId((Int32)fila["idMarca"]);
            articulo.TipoComision = RepositorioTipoComisionArticulo.DevolverPorId((Byte)fila["IdTipoComisionArticulo"]);
            articulo.TipoImpuesto = RepositorioTipoImpuestoArticulo.DevolverPorId((Byte)fila["IdTipoImpuestoArticulo"]);
            articulo.TipoCosto = RepositorioTipoCostoArticulo.DevolverPorId((Byte)fila["idTipoCostoArticulo"]);
            //TODO: PROMOCION
            //articulo.Promocion = RepositorioPromocion.DevolverPorId((Int32)fila["IdPromocion"]);
            articulo.Codigo = fila["codigo"].ToString();
            articulo.Nombre = fila["nombre"].ToString();
            articulo.ExistenciaMinima = (Int32)fila["existenciaMinimo"];
            articulo.ExistenciaMaxima = (Int32)fila["existenciaMaximo"];
            articulo.DescripcionServicio = fila["DescripcionServicio"].ToString();
            articulo.Costo = (Decimal)fila["Costo"];
            articulo.Comision = (Decimal)fila["Comision"];
            articulo.ComisionMaxima = (Decimal)fila["ComisionMaxima"];
            articulo.Iva = (Decimal)fila["Iva"];
            articulo.Impuesto = (Decimal)fila["Impuesto"];
            articulo.EstaEliminado = (Boolean)fila["EstaEliminado"];

            if (fila.Table.Columns.Contains("TieneImagen"))
                articulo.TieneImagen = (Boolean)fila["TieneImagen"];
            if (fila.Table.Columns.Contains("TieneObservacion"))
                articulo.TieneObservacion = (Boolean)fila["TieneObservacion"];
            return articulo;
        }

        private DetalleArticulo FilaADetalle(DataRow fila, Articulo articulo)
        {
            var detalle = new DetalleArticulo();
            detalle.Articulo = articulo;
            detalle.Observacion = (String)fila["Observacion"];
            if (fila["Imagen"] != DBNull.Value)
                detalle.Imagen = ManejoImagen.ByteAImagen((Byte[])fila["Imagen"]);
            return detalle;
        }

        public Articulo DevolverPorIdConDetalle(Int32 idArticulo)
        {
            var entidad = (from Articulo item in entidades
                           where item.Id == idArticulo
                           && item.Detalle != null
                           select item).FirstOrDefault();
            if (entidad == null)
            {
                using (DataSet ds = ServicioDatosArticulo.Articulos_DevolverPorIdConDetalle(idArticulo))
                {
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidad.Detalle = FilaADetalle(ds.Tables[1].Rows[0], entidad);
                        entidades.Add(entidad);
                    }
                }
            }
            return entidad;
        }

        public override Articulo DevolverPorId(Int32 id)
        {
            Articulo entidad = (from Articulo item in entidades where item.Id == id select item).FirstOrDefault();
            if (entidades != null)
            {
                using (DataSet ds = ServicioDatosArticulo.Articulos_DevolverPorId(id))
                {
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidades.Add(entidad);
                    }
                }
            }
            return entidad;
        }

        public void Insertar(Articulo entidad)
        {
            entidad.Id = ServicioDatosArticulo.Articulos_Insertar(entidad.Tipo.Id, entidad.Rubro.Id, entidad.DescuentoRecargo.Id, entidad.Marca.Id, entidad.TipoComision.Id,
                entidad.TipoImpuesto.Id, entidad.TipoCosto.Id, entidad.Promocion == null ? 4 : entidad.Promocion.Id, entidad.Codigo, entidad.Nombre, entidad.ExistenciaMinima,
                entidad.ExistenciaMaxima, entidad.DescripcionServicio, entidad.Costo, entidad.Comision, entidad.ComisionMaxima, entidad.Iva, entidad.Impuesto, entidad.EstaEliminado);
        }

        public void Modificar(Articulo entidad)
        {
            ServicioDatosArticulo.Articulos_Modificar(entidad.Id, entidad.Tipo.Id, entidad.Rubro.Id, entidad.DescuentoRecargo.Id, entidad.Marca.Id, entidad.TipoComision.Id,
                entidad.TipoImpuesto.Id, entidad.TipoCosto.Id, entidad.Promocion.Id, entidad.Codigo, entidad.Nombre, entidad.ExistenciaMinima,
                entidad.ExistenciaMaxima, entidad.DescripcionServicio, entidad.Costo, entidad.Comision, entidad.ComisionMaxima, entidad.Iva, entidad.Impuesto, entidad.EstaEliminado);
        }

        public void Eliminar(Articulo entidad)
        {
            ServicioDatosArticulo.Articulos_Eliminar(entidad.Id);
            entidad = null;
        }

        public void InsertarDetalle(DetalleArticulo detalle)
        {
            ServicioDatosArticulo.ArticulosDetalles_Insertar(detalle.Articulo.Id, detalle.Observacion, ManejoImagen.ImagenAByte(detalle.Imagen));
        }

        public void ModificarDetalle(DetalleArticulo detalle)
        {
            ServicioDatosArticulo.ArticulosDetalles_Modificar(detalle.Articulo.Id, detalle.Observacion, ManejoImagen.ImagenAByte(detalle.Imagen));
        }

        public List<Articulo> DevolverTodos()
        {
            using (DataSet ds = ServicioDatosArticulo.Articulos_DevolverTodos())
            {
                entidades = TablaALista(ds.Tables[0]);
            }
            return entidades;
        }

        public void Habilitar(Articulo articulo)
        {
            ServicioDatosArticulo.Articulos_Habilitar(articulo.Id);
            articulo.EstaEliminado = false;
        }

        #endregion

    }
}
